﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace FezPosterClient
{
    public partial class MainForm : Form
    {
        #region プロパティ
        private string session_id = "";

        private string selectItem = "";

        private string selectCharactor = "";

        private int hasStar = 0;

        private Dictionary<string, string> charactorList = new Dictionary<string, string>();

        private Changer changer = null;
        #endregion

        #region その他メソッド

        public MainForm()
        {
            InitializeComponent();

        }
        
        private bool isCurrentAccessPostar()
        {
            return webBrowser.Url.Host.Equals(Constant.postarDomain);
        }

        /// <summary>
        /// ステータスバーにメッセージ表示
        /// </summary>
        /// <param name="msg"></param>
        private void setStripMessage(string msg)
        {
            if (statusStrip == null) return;
            foreach (ToolStripItem item in statusStrip.Items)
            {
                if (item.Name == "stripLabel")
                {
                    item.Text = msg;
                    Application.DoEvents();
                    return;
                }
            }
        }

        #endregion

        #region コントロール切り替え系
        /// <summary>
        /// 購入パネルを表示するかどうか
        /// </summary>
        /// <param name="isEnable"></param>
        private void changeEnableRun(bool isEnable)
        {
            //isEnable = !isEnable;
            panelControls.Visible = isEnable;
            webBrowser.Visible = !isEnable;

            if (isEnable)
            {
                this.Width = panelControls.Width;
                this.Height = panelControls.Height + statusStrip.Height;
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
            }
        }

        /// <summary>
        /// 操作系の有効無効
        /// </summary>
        /// <param name="isEnable"></param>
        private void changeEnableCotrols(bool isEnable)
        {
            radioCharactor1.Enabled = isEnable;
            radioCharactor2.Enabled = isEnable;
            radioCharactor3.Enabled = isEnable;

            radioButton1.Enabled = isEnable;
            radioButton2.Enabled = isEnable;
            radioButton3.Enabled = isEnable;
            radioButton4.Enabled = isEnable;
            radioButton5.Enabled = isEnable;
            radioButton6.Enabled = isEnable;
            radioButton7.Enabled = isEnable;
            radioButton8.Enabled = isEnable;
            radioButton9.Enabled = isEnable;
            radioButton10.Enabled = isEnable;
            radioButton11.Enabled = isEnable;
            radioButton12.Enabled = isEnable;
            radioButton13.Enabled = isEnable;
            radioButton14.Enabled = isEnable;
            radioButton15.Enabled = isEnable;
            radioButton16.Enabled = isEnable;
            radioButton17.Enabled = isEnable;

            numericItemCount.Enabled = isEnable;
            buttonBuy.Enabled = isEnable;
            buttonCancel.Enabled = !isEnable;
        }

        #endregion

        #region セッション周りの処理

        private string getCurrentSessionId()
        {
            string cookie = webBrowser.Document.Cookie;

            foreach (string str in cookie.Split(';'))
            {
                string[] keyVal = str.Split('=');
                if (keyVal.Length != 2) continue;

                if (keyVal[0].Trim().Equals(Constant.sessionName))
                {
                    return keyVal[1].Trim();
                }
            }

            return "";
        }
        

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            this.changeEnableRun(false);
            charactorList.Clear();

            if (!this.isCurrentAccessPostar())
            {
                return;
            }

            if (e.Url.AbsoluteUri == Constant.loginUrl)
            {
                return;
            }

            string currentSession = this.getCurrentSessionId();
            WebClientEx client = Util.getWebClient(currentSession);

            setStripMessage("Postarからの応答待ち受け中");
            string doc = client.DownloadString(Constant.charactorListUrl);

             // ログインしているか判定
            setStripMessage("ログイン判定中");
            Regex regLogin = new Regex("ログインする必要があります", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            if (regLogin.Match(doc).Success)
            {
                setStripMessage("ログインされていません");
                return;
            }

            setStripMessage("キャラクターリスト取得中");
            Regex regAll = new Regex("<input type=\"radio\"[^>]*>[^<]*", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex regOther = new Regex("value=\"([^\"]*)[^>]*>([^ |^&nbsp]*)", RegexOptions.IgnoreCase | RegexOptions.Singleline);

            for (Match mc = regAll.Match(doc); mc.Success; mc = mc.NextMatch())
            {
                Match mg = regOther.Match(mc.Value);
                if (!mg.Success) continue;
                charactorList.Add(mg.Groups[1].Value, mg.Groups[2].Value);
            }

            if (charactorList.Count == 0)
            {
                setStripMessage("キャラクターリスト取得に失敗");
                return;
            }

            setStripMessage("所持スターの確認中");
            Regex regStar = new Regex("<div class=\"star\">(\\d+)</div>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match ms = regStar.Match(doc);
            if (!ms.Success)
            {
                setStripMessage("所持スターの確認に失敗");
            }
            hasStar = Int32.Parse(ms.Groups[1].Value);
            labelStar.Text = hasStar.ToString();
            session_id = currentSession;

            setStripMessage("コントロールのセットアップ中");
            int count = 1;
            radioCharactor1.Visible = false;
            radioCharactor2.Visible = false;
            radioCharactor3.Visible = false;
            foreach (KeyValuePair<string, string> charactor in charactorList)
            {
                switch(count){
                    case 1:
                        radioCharactor1.Text = charactor.Value;
                        radioCharactor1.Tag = charactor.Key;
                        radioCharactor1.Visible = true;
                        break;
                    case 2:
                        radioCharactor2.Text = charactor.Value;
                        radioCharactor2.Tag = charactor.Key;
                        radioCharactor2.Visible = true;
                        break;
                    case 3:
                        radioCharactor3.Text = charactor.Value;
                        radioCharactor3.Tag = charactor.Key;
                        radioCharactor3.Visible = true;
                        break;
                    default:
                        break;
                }
                count++;
            }

            this.changer = new Changer(this.session_id, statusStrip, labelStar);
            this.changeEnableRun(true);
            setStripMessage("");
        }

        private void radioItemsCheckedChanged(object sender, EventArgs e)
        {
            RadioButton radio = (RadioButton)sender;
            selectItem = radio.Tag.ToString();
        }

        private void radioCharactorsCheckedChanged(object sender, EventArgs e)
        {
            RadioButton radio = (RadioButton)sender;
            selectCharactor = radio.Tag.ToString();
        }

        private void buttonBuy_Click(object sender, EventArgs e)
        {
            if (this.selectCharactor.Length == 0)
            {
                MessageBox.Show("送付するキャラクターが選択されていません");
                return;
            }

            if (this.selectItem.Length == 0)
            {
                MessageBox.Show("アイテムが入力されていません");
                return;
            }

            int count = Decimal.ToInt32(numericItemCount.Value);

            if (count <= 0)
            {
                MessageBox.Show("個数が選択されていません");
                return;
            }

            changeEnableCotrols(false);
            changer.isStop = false;
            changer.run(selectCharactor, selectItem, count);
            changeEnableCotrols(true);
        }

        private void radioItems_MouseEnter(object sender, EventArgs e)
        {
            RadioButton button = (RadioButton)sender;

            if (!button.Enabled) return;
            string key = (string)button.Tag;
            string msg = "【" + Constant.ItemNames[key] + "】" + Constant.ItemPrice[key] + "スター";
            setStripMessage(msg);
        }

        private void radioItems_MouseLeave(object sender, EventArgs e)
        {
            RadioButton button = (RadioButton)sender;

            if (!button.Enabled) return;
            setStripMessage("");
        }

        private void buttonDebug_Click(object sender, EventArgs e)
        {
            setStripMessage("wait 1/3");
            Util.wait();
            setStripMessage("wait 2/3");
            Util.wait();
            setStripMessage("wait 3/3");
            Util.wait();
            setStripMessage("wait fin");
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            changer.isStop = true;
        }

    }
}
